package net.facelib.sdk;

import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import net.gdface.image.MatType;
import net.gdface.utils.ThreadFactoryBuilder;

import java.io.File;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import com.google.common.base.Predicate;

import static net.facelib.sdk.FaceCaptureLog.CAPTURER_LOGGER;
import static net.gdface.utils.ConditionChecks.checkState;
import static net.gdface.utils.ConditionChecks.checkArgument;

/**
 * 人脸识别应用{@link SurfaceView},{@link TextureView}封装
 * @author guyadong
 *
 */
public final class FaceViewAndroidBuilder {

    /** 摄像头对象 */
    private volatile Camera camera;
    /** 摄像ID */
    private int cameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
    /** 摄像预览界面旋转角度 */
    private int orientation = 90;
    /** 摄像头预览分辨率的宽 */
    private int previewWidth = 640;
    /** 摄像头预览分辨率的高 */
    private int previewHeight = 480;
    private FaceCapturer faceCapturer = FaceCapturer.getInstanceUnchecked();
    /** callback buffer数量 */
    private int callbackBufferNum = 1;
	private Predicate<Camera.Parameters> parameterCustomConfig;
    private SurfaceHolderCallback surfaceHolderCallback = new SurfaceHolderCallback().setFaceView(this);
	private TextureViewListener textureListener = new TextureViewListener().setFaceView(this);
	private CameraPreviewCallback previewCallback;
	private Runnable onFirstFrame;
	private boolean asyncRegisterFaces = true;
	private boolean trace = true;
	public FaceViewAndroidBuilder() {
	}

    /**
	 * 摄像头初始化相关参数
	 *
	 * @param cameraID 摄像头ID,默认后置摄像头
	 * @param orientation 旋转角度,[0,90,180,270],默认90
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setCameraParams(int cameraID, int orientation) {
	    this.cameraID = cameraID;
	    checkArgument(orientation == 0 || orientation == 90 || orientation == 180 || orientation ==270,
	    		"Invalid orientation %s,[0,90,180,270] required",orientation);
	    this.orientation = orientation;
	    return this;
	}

	/**
	 * 配置摄像头预览分辨率,默认640x480
	 *
	 * @param width
	 * @param height
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setPreviewSize(int width, int height) {
	    this.previewWidth = width;
	    this.previewHeight = height;
	    return this;
	}

	/**
	 * 设置 callback buffer数量,默认1
	 * @param callbackBufferNum 小于等于0忽略
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setCallbackBufferNum(int callbackBufferNum) {
		if(callbackBufferNum > 0){
			this.callbackBufferNum = callbackBufferNum;
		}
		return this;
	}

	/**
	 * 设置摄像自定义参数配置实例,应用层可以通过提供{@link Predicate}对象自定义摄像头参数<br>
	 * 忽略返回{@link Predicate#apply(Object)}返回值
	 * @param parameterCustomConfig
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setParameterCustomConfig(Predicate<Camera.Parameters> parameterCustomConfig) {
		this.parameterCustomConfig = parameterCustomConfig;
		return this;
	}

	/**
	 * 设置人脸视频检测接口实例
	 * @param faceCapturer
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setFaceCapturer(FaceCapturer faceCapturer) {
		if(null != faceCapturer){
			this.faceCapturer = faceCapturer;
		}
		return this;
	}
	
	/**
	 * 开启调试日志输出
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder enableDebugLog() {
		if(null != faceCapturer){
			faceCapturer.enableDebugLog();
		}
		return this;
	}
	/**
	 * 设置当执行关闭({@link FaceCapturer#close()})时是否释放算法模块占用的资源,默认{@code false}
	 * @see  FaceCapturer#setReleaseSdkModulesOnClose(boolean)
	 */
	public FaceViewAndroidBuilder setReleaseSdkModulesOnClose(boolean releaseSdkModulesOnClose) {
		if(null != faceCapturer){
			faceCapturer.setReleaseSdkModulesOnClose(releaseSdkModulesOnClose);
		}
		return this;
	}

	/**
	 * @see FaceCapturer#setCallback(FaceCaptureCallback)
	 */
	public FaceViewAndroidBuilder setFaceCaptureCallback(FaceCaptureCallback callback) {
		if(null != faceCapturer){
			faceCapturer.setCallback(callback);
		}
		return this;
	}
	/**
	 * @see FaceCapturer#setFeature(int[])
	 */
	public FaceViewAndroidBuilder setFaceCaptureFeature(int... features) {
		if(null != faceCapturer){
			faceCapturer.setFeature(features);
		}
		return this;
	}

	/**
	 * @see FaceCapturer#registerUser(String, URL, String) 
	  */
	public FaceViewAndroidBuilder registerUser(String userID, URL photo, String description) {
		if(null != faceCapturer){
			faceCapturer.registerUser(userID, photo, description);
		}
		return this;
	}
	/**
	 * @see FaceCapturer#registerUser(String, File, String) 
	  */
	public FaceViewAndroidBuilder registerUser(String name, File imgFile, String description) {
		if(null != faceCapturer){
			faceCapturer.registerUser(name, imgFile, description);
		}
		return this;
	}
	/**
	 * @see FaceCapturer#setRecognitionParam(int, double)
	 */
	public FaceViewAndroidBuilder setRecognitionParam(int fseMaxRows, double similarityThreshold) {
		if(null != faceCapturer){
			faceCapturer.setRecognitionParam(fseMaxRows, similarityThreshold);
		}
		return this;
	}

	/**
	 * 设置{@link android.view.SurfaceView}回调函数,只对{@link #buildCameraView(View)}有效
	 * @param surfaceHolderCallback 为{@code null}忽略
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setSurfaceHolderCallback(SurfaceHolderCallback surfaceHolderCallback) {
		if(null != surfaceHolderCallback){
			this.surfaceHolderCallback = surfaceHolderCallback.setFaceView(this);
		}
		return this;
	}

	/**
	 * 设置{@link android.view.TextureView}侦听器,只对{@link #buildCameraView(View)}有效
	 * @param textureListener 为{@code null}忽略
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setTextureListener(TextureViewListener textureListener) {
		if(null != textureListener){
			this.textureListener = textureListener.setFaceView(this);
		}
		return this;
	}

	/**
	 * 指定当收到第一帧图像时要执行的逻辑
	 * @param onFirstFrame
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setOnFirstFrame(Runnable onFirstFrame) {
		this.onFirstFrame = onFirstFrame;
		return this;
	}

	/**
	 * 指定是否异步执行用户人脸特征注册{@link FaceCapturer#registerAllFaces(AtomicInteger)},默认为{@code true},
	 * 如果指定为{@code false}则必须在合适的位置调用{@link FaceCapturer#registerAllFaces(AtomicInteger)}完成用户人脸数据注册
	 * @param asyncRegisterFaces
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setAsyncRegisterFaces(boolean asyncRegisterFaces) {
		this.asyncRegisterFaces = asyncRegisterFaces;
		return this;
	}

	/**
	 * 设置是否输出异常堆栈,默认{@code true}
	 * @param trace
	 * @return 当前对象
	 */
	public FaceViewAndroidBuilder setTrace(boolean trace) {
		this.trace = trace;
		return this;
	}

	public int getPreviewWith(){
		return previewHeight;
	}
	public int getPreviewHeight(){
		return previewHeight;
	}
	
	public int getOrientation() {
		return orientation;
	}

	public Camera getCamera() {
		return camera;
	}

	public int getCallbackBufferNum() {
		return callbackBufferNum;
	}

	public FaceCapturer getFaceCapturer() {
		return faceCapturer;
	}
	
	public boolean isAsyncRegisterFaces() {
		return asyncRegisterFaces;
	}

	public boolean isTrace() {
		return trace;
	}

	public Runnable getOnFirstFrame() {
		return onFirstFrame;
	}

	/**
	 * 调用{@link FaceCaptureCallback#onCameraException(Throwable)}方法处理摄像头设备异常,
	 * 如果调用时抛出异常则日志输出
	 * @param e undeclared exception
	 */
	protected void doOnCameraException(Throwable e){
		try {
			FaceCapturer faceCapturer = this.faceCapturer;
			if(null != faceCapturer){
				faceCapturer.getCallback().onCameraException(e);
			}else{
				CAPTURER_LOGGER.log("{}:{}",e.getClass().getName(),e.getMessage());
				CAPTURER_LOGGER.logTrace(trace, e);				
			}
		} catch (Throwable x) {
			CAPTURER_LOGGER.log("{}:{}",x.getClass().getName(),x.getMessage());
			CAPTURER_LOGGER.logTrace(trace, x);
		}
	}
	/**
	 * 初始化用于显示摄像头视频的{@link TextureView}或{@link SurfaceView}实例,
	 * @return always view
	 */
	public <T extends View>T buildCameraView(T view){
		if(view instanceof SurfaceView){
			SurfaceView surfaceView = (SurfaceView)view;
			SurfaceHolder surfaceHolder = surfaceView.getHolder();
			surfaceHolder.addCallback(surfaceHolderCallback);
			previewCallback = new CameraPreviewCallback(this);
		}else if(view instanceof TextureView){
			TextureView textureView = (TextureView)view;
			textureView.setSurfaceTextureListener(textureListener);
			previewCallback = new CameraPreviewCallback(this);
		} else {
			checkArgument(null == view,"UNSUPPORT View type {},SurfaceView,TextView required",view.getClass().getSimpleName());
		}
		if(null != faceCapturer){
			this.faceCapturer.setCaptureMat(MatType.NV21, previewWidth, previewHeight);
			this.faceCapturer.setTrace(trace);
		}
        return view;
	}
	/**
	 * 打开并初始化摄像头
     * @return 初始化成功或已经被初始化返回@true},否则返回{@code false}
	 */
	private boolean initCamera() {
		// double  check
		if (null == camera) {
			synchronized (this) {
				CAPTURER_LOGGER.log("initialize camera");
				if (null == camera) {
					// 摄像头初始化成功标记
					boolean initialized = false;
					try {
						checkState(previewCallback != null,
								"view not created, please call buildSurfaceView or buildTextureView firstly");
						camera = Camera.open(cameraID);
						CAPTURER_LOGGER.log("open camera");
						Camera.Parameters parameters = camera.getParameters();
						checkState(previewSizeMatched(parameters.getSupportedPreviewSizes()),
								"摄像头不支持预览分辨率 {}x{}",previewWidth,previewHeight);
						parameters.setPreviewSize(previewWidth, previewHeight);
						CAPTURER_LOGGER.log("配置摄像头预览分辨率 {}x{}",previewWidth,previewHeight);
						if(null != parameterCustomConfig){
							CAPTURER_LOGGER.log("自定义配置摄像头参数");
							parameterCustomConfig.apply(parameters);
						}
						camera.setParameters(parameters);
						initCallbackBuffer(camera,callbackBufferNum);
						CAPTURER_LOGGER.log("设置摄像头缓存buffer");
		        		camera.setPreviewCallbackWithBuffer(previewCallback);
		        		CAPTURER_LOGGER.log("开启摄像头  设置回调数据接口");
						camera.setDisplayOrientation(orientation);
						CAPTURER_LOGGER.log("设置摄像头 旋转角度 " + orientation);
						initialized = true;
		        		CAPTURER_LOGGER.log("设置摄像头  初始化成功");
					} catch (Throwable e) {
						doOnCameraException(e);
					} finally{
						if(!initialized){
							// 启动失败,关闭摄像头
							destroyCamera();
						}
					}
					return initialized;
				}
			}
		}
		return true;
	}
	
	/**
	 * 释放摄像头
	 */
	private void destroyCamera() {
		// double check
		if (null != camera) {
			synchronized (this) {
				if (null != camera) {
					try {
						CAPTURER_LOGGER.log("release camera");
						camera.release();
						camera = null;
					} catch (RuntimeException e) {
						CAPTURER_LOGGER.log("{}:{}",e.getClass().getName(),e.getMessage());
						CAPTURER_LOGGER.logTrace(trace, e);
					}	
				}
			}
		}
	}
	/**
	 * 执行{@link FaceCapturer#close()}
	 */
	private void closeFaceCapturer(){
		FaceCapturer faceCapturer = this.faceCapturer;					
		if(null != faceCapturer){
			faceCapturer.close();

			// 参见 CameraPreviewCallback.notifyIfCapturerClosed
			synchronized (faceCapturer) {
				try {
					CAPTURER_LOGGER.log("CAPSIGN: wait close singal of capturer  {}", faceCapturer);
					// 等到视频捕获线程的结束信号后,再执行摄像头关闭动作，防止捕获线程有资源泄露
					faceCapturer.wait();
				} catch (InterruptedException e) {
					// DO NOTHING
				}
			}
		}
	}
	/**
	 * 执行{@link FaceCapturer#open()}
	 */
	private void openFaceCapturer(){
		FaceCapturer faceCapturer = this.faceCapturer;					
		if(null != faceCapturer){
			try {
				faceCapturer.open();
			} catch (Throwable e) {
				faceCapturer.doOnUndeclaredException(e);
			}
		}
	}
	/**
	 * 关闭显示，同时释放摄像头
	 */
	private void stopPreview() {
		// double check
		if (null != camera) {
			synchronized (this) {
				if (null != camera) {
					try {
						CAPTURER_LOGGER.log("stop preview");
						closeFaceCapturer();
						camera.setPreviewCallbackWithBuffer(null);
						camera.stopPreview();
						destroyCamera();
					} catch (Throwable e) {
						CAPTURER_LOGGER.log("{}:{}",e.getClass().getName(),e.getMessage());
						CAPTURER_LOGGER.logTrace(trace, e);
					} 
				}
			}
		}
	}
	/**
	 * 异步执行{@link #stopPreview()}
	 */
	private void stopPreviewAsync() {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				stopPreview();
				
			}
		},"stop-preview").start();
	}
	private boolean previewSizeMatched(List<Camera.Size> previewSizes) {
	    for (Camera.Size size : previewSizes) {
	        if (previewWidth == size.width && previewHeight == size.height) {
	            return true;
	        }
	    }
	    return false;
	}
	
	public static FaceViewAndroidBuilder builder(){
		return new FaceViewAndroidBuilder();
	}
	private static Executor getExecutor(){
		return SingletonExecutor.ONE_EXECUTOR;
	}
	/**
	 * 弱引用方式保存所有callback buffer,
	 * 当弱引用有效时就使用已经有的buffer,避免频繁创建callback buffer
	 */
	private static final HashSet<WeakReference<byte[]>> callbackBufferCache = new HashSet<>();
	/**
	 * 初始化摄像头视频缓冲区
	 * @param camera
	 * @param bufferNum callback buffer数量
	 */
	private static synchronized void initCallbackBuffer(Camera camera, int bufferNum){
	    if(null != camera){
	        Camera.Parameters parameters = camera.getParameters();
	        Camera.Size previewSize = parameters.getPreviewSize();
	        int bpp = ImageFormat.getBitsPerPixel(parameters.getPreviewFormat());
	        int bufferSize = previewSize.width * previewSize.height * bpp / 8;
	        int addCount = 0;
	        byte[] buffer;
	        /** 遍历callbackBufferCache查找有效的弱引用 */
	        for(Iterator<WeakReference<byte[]>> itor = callbackBufferCache.iterator(); itor.hasNext() ; ){
	        	WeakReference<byte[]> ref = itor.next();
	        	 if( null != (buffer = ref.get()) && buffer.length == bufferSize){
	        		 /** 弱引用有效且数组长度匹配,则不必再申请分配新的buffer,直接使用弱引用保存的buffer */
	        		 CAPTURER_LOGGER.log("reuse old callback buffer saved by weakReference");
	        		 camera.addCallbackBuffer(buffer);
	        		 addCount ++;
	        	 }else{
	        		 /** 删除无效的弱引用 */
	        		 ref.clear();
	        		 itor.remove();
	        	 }
	        }
	        /** 
	         * callbackBufferCache 中的有效 callback buffer 数量不足时
	         * 添加callback buffer 并保存到 callbackBufferCache
	         */
	        for(; addCount < bufferNum; ++addCount){
	        	CAPTURER_LOGGER.log("create callback buffer,and  save it with weakReference");
	        	/** 分配新的 callback buffer */
	        	buffer = new byte[bufferSize];
	        	callbackBufferCache.add(new WeakReference<>(buffer));
	            camera.addCallbackBuffer(buffer);
	        }
	    }
	}

	/**
	 * 反射方式调用 {@code Surface.allocateBuffers()} 预分配buffer
	 * @param surfaceHolder
	 */
	private static void preallocateBuffersForSurface(SurfaceHolder surfaceHolder){
		if(surfaceHolder != null){
			Surface surface = surfaceHolder.getSurface();
			try {
				if(surface.isValid()){
	    			Surface.class.getMethod("allocateBuffers").invoke(surface);
	    			CAPTURER_LOGGER.log("Surface 预分配buffer成功");
				}else{
					CAPTURER_LOGGER.log("无效的Surface实例");
				}
			}catch (NoSuchMethodException e){
				CAPTURER_LOGGER.log("没有找到 Surface.allocateBuffers() 方法");
			} catch (InvocationTargetException e){
				CAPTURER_LOGGER.log("调用 allocateBuffers 失败 {}:{}",e.getTargetException().getClass().getName(),e.getTargetException().getMessage());
			} catch (Throwable e){
				CAPTURER_LOGGER.log("调用 allocateBuffers 失败 {}:{}",e.getClass().getName(),e.getMessage());
			}
		}
	}
	/**
     * {@link android.view.SurfaceHolder.Callback}默认实现,应用层可以继承此类添加自定义业务逻辑
     * @author guyadong
     *
     */
    public static class SurfaceHolderCallback implements SurfaceHolder.Callback {
    	private FaceViewAndroidBuilder faceView;
        public SurfaceHolderCallback() {			
		}

		@Override
        public final void surfaceCreated(SurfaceHolder holder) {
            CAPTURER_LOGGER.log("surfaceCreated");

            preallocateBuffersForSurface(holder);
            synchronized (faceView) {
                if (faceView.initCamera()) {
                	faceView.openFaceCapturer();
            		try {
            			faceView.camera.setPreviewDisplay(holder);
            			faceView.camera.startPreview();
            		} catch (Throwable e) {
            			faceView.doOnCameraException(e);
            		}
            	}
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            CAPTURER_LOGGER.log("surfaceDestroyed");
            faceView.stopPreviewAsync();
        }

		private SurfaceHolderCallback setFaceView(FaceViewAndroidBuilder faceView) {
			this.faceView = faceView;
			return this;
		}
        
    };
    /**
     * {@link android.view.TextureView.SurfaceTextureListener}默认实现,应用层可以继承此类添加自定义业务逻辑
     * @author guyadong
     *
     */
    public static class TextureViewListener implements TextureView.SurfaceTextureListener{
    	private FaceViewAndroidBuilder faceView;
        public TextureViewListener() {
		}
		@Override
		public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            CAPTURER_LOGGER.log("TextureAvailable");
            synchronized (faceView) {
            	if (faceView.initCamera()) {
            		faceView.openFaceCapturer();
            		try {
            			faceView.camera.setPreviewTexture(surface);
            			faceView.camera.startPreview();
            		} catch (Throwable e) {
            			faceView.doOnCameraException(e);
            		}
            	}
			}
		}

		@Override
		public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
			
		}

		@Override
		public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            CAPTURER_LOGGER.log("TextureDestroyed");
            faceView.stopPreviewAsync();
			return true;
		}

		@Override
		public void onSurfaceTextureUpdated(SurfaceTexture surface) {
			
		}

		private TextureViewListener setFaceView(FaceViewAndroidBuilder faceView) {
			this.faceView = faceView;
			return this;
		}
	}
    /**
     * {@link android.hardware.Camera.PreviewCallback}实现
     * @author guyadong
     *
     */
    public static class CameraPreviewCallback implements Camera.PreviewCallback {
    	private FaceViewAndroidBuilder builder;
    	private volatile boolean firstFrame = true;
    	/**
    	 * 构造方法
    	 */
    	public CameraPreviewCallback() {
    		this(null);
    	}
        /**
         * 构造方法
         * @param builder builder
         */
        public CameraPreviewCallback(FaceViewAndroidBuilder builder) {
			this.builder = builder;
		}
        protected void onFirstFrame(){
        	Runnable runnable;
        	if(null != builder && null != (runnable = builder.getOnFirstFrame())){
        		runnable.run();
        	}
        }
        
        protected final FaceViewAndroidBuilder getFaceView() {
			return builder;
		}
		public CameraPreviewCallback setFaceView(FaceViewAndroidBuilder faceView) {
			this.builder = faceView;
			return this;
		}
		public CameraPreviewCallback reset(){
			this.firstFrame = true;
			return this;
		}
		
		private static void notifyIfCapturerClosed(FaceCapturer faceCapturer){
    		if (null != faceCapturer) {
    			if(faceCapturer.isClosed()){
    				synchronized (faceCapturer) {
    					CAPTURER_LOGGER.log("CAPSIGN: wakeup all threads that be waiting for capturer {}",faceCapturer);
    					faceCapturer.notifyAll();
					}
    			}
    		}
		}
		private void doOnPreviewFrame(byte[] data, Camera camera) {
    		/** 复制变量,防止在摄像头工作时,调用 setFaceCaputureCallBack 设置为 null 导致异常 */ 
			FaceCapturer faceCapturer = (builder == null) ? null : builder.faceCapturer;
            try {
            	if(firstFrame){
            		firstFrame = false;
            		if(builder.asyncRegisterFaces){
            			// 异步执行用户注册
                		if (null != faceCapturer) {
                			faceCapturer.registerAllFaces(new AtomicInteger());
                		}
            		}
            		onFirstFrame();
            	}
            	if (null != faceCapturer) {
            		faceCapturer.capture(data);
            	}
            } catch (RuntimeException e) {
				CAPTURER_LOGGER.log("{}:{}",e.getClass().getName(),e.getMessage());
				CAPTURER_LOGGER.logTrace(builder == null ? false : builder.trace, e);
            }finally {
            	notifyIfCapturerClosed(faceCapturer);
                // 将buffer添加回缓冲区队列
            	camera.addCallbackBuffer(data);
            }
        }
        @Override
        public final void onPreviewFrame(final byte[] data, final Camera camera) {
    		try {
    			// 向线程池提交异步执行任务
    			getExecutor().execute(new Runnable() {
    				
    				@Override
    				public void run() {
    					doOnPreviewFrame(data,camera);
    				}
    			});
			} catch (RejectedExecutionException e) {
				// 任务被拒绝时,放弃任务,避免任务积压
				// 将buffer添加回缓冲区队列
            	camera.addCallbackBuffer(data);
            	CAPTURER_LOGGER.log("DISCARD TASK caused by {}",e.getClass().getName());
			}
        }
    }
    private static class SingletonExecutor{
		/** 
		 * 默认单线程池对象<br>
		 * 队列容量为1,当队列中有未完成任务时再增加新任务会抛出{@link RejectedExecutionException}异常
		 */
		private static final ThreadPoolExecutor ONE_EXECUTOR = new ThreadPoolExecutor(1, 1,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(1),
                new ThreadFactoryBuilder().setNameFormat("camera-callback-%d").setDaemon(true).build());
		static{
			ThreadFactoryBuilder.addDelayedShutdownHook(ONE_EXECUTOR, 20, TimeUnit.SECONDS);
		}
	}    
}